package com.api.oa.services.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.api.oa.common.UserType;
import com.api.oa.config.UserContext;
import com.api.oa.mapper.YQInsEntityMapper;
import com.api.oa.mapper.YQServiceOptMapper;
import com.api.oa.mapper.YQTaskMapper;
import com.api.oa.mapper.YQUserMapper;
import com.api.oa.model.entity.YQServiceOpt;
import com.api.oa.model.entity.YQTask;
import com.api.oa.model.entity.YQUser;
import com.api.oa.model.params.YQTaskParam;
import com.api.oa.model.vo.YQInsEntityVO;
import com.api.oa.model.vo.YQTaskVO;
import com.api.oa.model.vo.YQTaskWeekVO;
import com.api.oa.services.YQTaskService;
import com.api.oa.utils.CoordinateUtil;
import com.api.oa.utils.LocalRedis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@Service
public class YQTaskServiceImpl implements YQTaskService {

    @Autowired
    private YQTaskMapper mapper;
    @Autowired
    private YQUserMapper yqUserMapper;
    @Autowired
    private YQInsEntityMapper yqInsEntityMapper;
    @Autowired
    private YQServiceOptMapper yqServiceOptMapper;

    @Override
    public YQTaskVO findOneByTaskId(Long id) {
        YQTaskVO oneByTaskId = mapper.findOneByTaskId(id);
        String taskContent = oneByTaskId.getTaskContent();
        if(!StrUtil.isEmptyIfStr(taskContent)){
            String[] split = taskContent.split(",");
            List<String> collect = Arrays.stream(split).collect(Collectors.toList());
            List<YQServiceOpt> yqServiceOpts = yqServiceOptMapper.listOpts(collect);
            oneByTaskId.setOpts(yqServiceOpts);
        }
        return oneByTaskId;
    }

    @Value("${minDis}")
    private Double minDis = 100D;

    @Autowired
    LocalRedis redis;


    @Override
    public Integer add(YQTask entity) throws Exception {
        if (UserContext.getRole() == UserType.INS) {
            entity.setInsCodeUser(UserContext.getUserId());
        }
        if (entity.getPatientUser() == null || entity.getCareUser() == null) {
            throw new Exception("参与者不能未空");
        }
        entity.setTaskStatus(0);
        return mapper.insert(entity);
    }

    @Override
    public void remove(Long id) {
        mapper.delete(id);
    }

    @Override
    public Integer update(YQTask entity) {
        return mapper.update(entity);
    }

    @Override
    public PageInfo<YQTaskVO> list(Long pid, String taskStats, String keyWord, String start, String end, Integer pageIndex, Integer pageSize) {
        if (UserContext.getRole() == UserType.INS) {
            pid = UserContext.getUserId();
        }
        PageHelper.startPage(pageIndex, pageSize);
        PageHelper.orderBy("taskDate desc,taskId desc");
        return new PageInfo<>(mapper.list(pid, taskStats, keyWord, start, end));
    }

    @Override
    public PageInfo<YQTaskVO> queryByUserId(Long careUser, String date, Boolean isCare, Integer pageIndex, Integer pageSize) {
        PageHelper.startPage(pageIndex, pageSize);
        PageHelper.orderBy("taskDate desc,taskId desc");
        return new PageInfo<>(mapper.listByCare(careUser, date, isCare));
    }

    //web
    @Override
    public PageInfo<YQTaskVO> queryByInsUser(Long insUserId, String taskStats, String keyWord, String start, String end, Integer pageIndex, Integer pageSize) {
        if (UserContext.getRole() == UserType.INS) {
            insUserId = UserContext.getUserId();
        }
        PageHelper.startPage(pageIndex, pageSize);
        PageHelper.orderBy("taskDate desc,taskId desc");
        return new PageInfo<>(mapper.queryPatientReq(insUserId, taskStats, keyWord, start, end));
    }

    //安卓
    @Override
    public PageInfo<YQTaskVO> queryTaskByPatient(Long insUserId, Boolean isRange, Integer pageIndex, Integer pageSize) {
        PageHelper.startPage(pageIndex, pageSize);
        PageHelper.orderBy("taskDate desc,taskId desc");
        return new PageInfo<>(mapper.queryTaskByPatient(insUserId, isRange));
    }

    @Override
    public Integer dispatchCare(YQTask entity) {
        return mapper.updateCareUserByTaskId(entity.getTaskId(), entity.getCareUser());
    }

    @Override
    public PageInfo<YQTaskVO> queryMyService(Long userId, Integer pageIndex, Integer pageSize) {
        PageHelper.startPage(pageIndex, pageSize);
        PageHelper.orderBy("taskDate desc,taskId desc");
        return new PageInfo<>(mapper.queryService(userId));
    }


    @Override
    public PageInfo<YQTaskVO> queryServiceByCare(Long userId, Integer pageIndex, Integer pageSize) {
        PageHelper.startPage(pageIndex, pageSize);
        PageHelper.orderBy("taskDate desc,taskId desc");
        return new PageInfo<>(mapper.queryServiceByCare(userId));
    }

    @Override
    public Integer setTaskStaisfication(Long taskId, String value) throws Exception {
        YQTaskVO oneByTaskId = mapper.findOneByTaskId(taskId);
        if (oneByTaskId == null) throw new Exception("护理服务不存在");
        if (oneByTaskId.getTaskStatus() < 2) {
            throw new Exception("服务未完成，不可评价");
        }
        return mapper.updateStatisfcation(taskId, value);
    }

    @Override
    public Integer startTaskService(Long taskId, Double lat, Double lng) throws Exception {
        YQTaskVO oneByTaskId = mapper.findOneByTaskId(taskId);
        if (oneByTaskId == null) throw new Exception("任务不存在");
        if (oneByTaskId.getTaskStatus() != 0) throw new Exception("服务状态不正确");
        //比对坐标
        if(oneByTaskId.getLat() != null && oneByTaskId.getLng()!=null){
            double v = CoordinateUtil.latLngDist(lng, lat, oneByTaskId.getLng(), oneByTaskId.getLat());
        }
        //if (v > minDis) throw new Exception("您还未到患者家中,无法进行服务");
        redis.set(String.format("time_%d", taskId), DateUtil.currentSeconds(), 3600 * 24);
        return mapper.updateStatus(taskId, 1); //服务中
    }

    @Override
    @Transactional
    public Integer requestBatch(YQTaskParam entity) {
        if (UserContext.getRole() == UserType.INS) {
            entity.setInsCodeUser(UserContext.getUserId());
        }
        Set<Long> patientUsers = entity.getPatientUsers();
        patientUsers.stream().forEach(i -> {
            YQTask yqTask = new YQTask();
            yqTask.setTaskStatus(0);
            yqTask.setTaskDate(entity.getTaskDate());
            yqTask.setInsCodeUser(entity.getInsCodeUser());
            yqTask.setCareUser(entity.getCareUser());
            yqTask.setPatientUser(i);
            mapper.insert(yqTask);
        });
        return 1;
    }

    @Override
    public YQTaskVO one(Long id) {
        return mapper.findOne(id);
    }

    @Override
    public YQTaskVO info(Long id) {
        return mapper.findOneByID(id);
    }


    @Override
    public List<YQTaskWeekVO> pageWeek(String start, String end, Long careUser) {
        return mapper.pageByWeek(start, end, careUser);
    }


    @Override
    public Integer verifyCareByScanQR(String code, Long taskId, Double lat, Double lng) throws Exception {
        Object o = redis.get(code);
        if (o == null) throw new Exception("二维码已经过期");
        YQTaskVO oneByTaskId = mapper.findOneByTaskId(taskId);
        if (oneByTaskId.getPatientUser() != (Long) o) throw new Exception("该患者不是您正在服务的本人");
        YQTaskVO oneByUserId = mapper.findOneByUserId((Long) o);
        if (oneByUserId == null) throw new Exception("患者不存在");
        double v = CoordinateUtil.latLngDist(lng, lat, oneByUserId.getLng(), oneByUserId.getLat());
        if (v > minDis) throw new Exception(String.format("您与患者的距离%.2f,多余%.2f米，无法服务", v, minDis));
        if (oneByTaskId.getTaskStatus() > 0) throw new Exception("该患者正在被服务或者已完成服务");
        redis.set(String.format("time_%d", taskId), DateUtil.currentSeconds(), 3600 * 24);
        return 1;
    }


    @Override
    public Integer queryLeftPatient(Long careUser, String date) {
        return mapper.listByCare(careUser, date, false).size();
    }

    @Override
    public Integer finishTaskById(Long id) {
        Object o = redis.get(String.format("time_%d", id));
        long time = 0;
        if (o != null) {
            Long start = (Long) o;
            time = DateUtil.currentSeconds() - start;
        }
        return mapper.updateTimeById(id, 2, time); //执行完成
    }


    @Override
    public Integer request(YQTask entity) throws Exception {
        if (DateUtil.date(entity.getTaskDate()).isBefore(DateUtil.parseDate(DateUtil.today()))) {
            throw new Exception("申请今日及以后的护理");
        }
        YQUser one = yqUserMapper.findOne(entity.getPatientUser());
        if (one == null) throw new Exception("您不是病患,不可以申请");
        YQInsEntityVO oneByInsCode = yqInsEntityMapper.findOneByInsCode(one.getBelongInsCode());
        entity.setInsCodeUser(oneByInsCode.getUserId());
        entity.setTaskStatus(0);
        return mapper.insert(entity);
    }


}
